#ifndef __D_LINK_LIST__
#define __D_LINK_LIST__

// struct T : dllist::node
template<class T>
struct dllist
{
	struct node
	{
		node*	_blink;
		node*	_flink;
		node() : _blink(this), _flink(this)
		{}
		T * next() { return (T*)_flink; };
		T * prev() { return (T*)_blink; };
	};

	node*	_root;

	//T*	_first;
	//T*	_last;

	dllist() : _root(0)
	{
		//_root._blink = &_root;
		//_root._flink = &_root;
	}
	~dllist()
	{
		
	}
	T * first()
	{
		return _root ? (T*)_root : 0;
		//return (T *)_root._flink;
	}
	//T * last()
	//{
	//	return _root ? (T*)_root : 0;
	//	//return (T *)_root._blink;
	//}
	bool is_empty()
	{
		return _root == 0;
		//return _root._blink == &_root || _root._flink == &_root;
	}

	void link_front( node * insert )
	{
		unlink( insert );
		if( !_root ) 
			_root = insert;
		else 
			link_backward( _root, insert );
	}

	void link_back( node * insert )
	{
		unlink( insert );
		if( !_root ) 
			_root = insert;
		else 
			link_forward( _root, insert );
	}

	void unlink( node* self )
	{
		if( self == _root )
		{
			_root = self->_flink;
			if( _root == self )
				_root = 0;
		}
		self->_blink->_flink = self->_flink;
		self->_flink->_blink = self->_blink;
		self->_blink = self;
		self->_flink = self;
	}
protected:
	void link_forward( node* self, node* insert )
	{
		//unlink( insert );
		insert->_flink = self->_flink;
		insert->_blink = self;
		self->_flink->_blink = insert;
		self->_flink = insert;
	}

	void link_backward( node* self, node* insert )
	{
		//unlink( insert );
		insert->_flink = self;
		insert->_blink = self->_blink;
		self->_blink->_flink = insert;
		self->_blink = insert;
	}

};


#endif